/**
\page page_observers Observers
 
<table CELLPADDING=0 style="width:100%;
  table-layout:fixed;
	margin:0px 0px 0px 0px;
	border-width:0px 0px 0px 0px; 
	border-color:#7F7F7F;">
<tr> 

<td style="width:80%; padding:0px 5px 0px 0px; vertical-align: text-top; text-align: left">
<h1 style="margin:0px; padding:0px">Overview</h1>

The Qtilities::Core::Observer class provides a powerful implementation of the subject - observer programming pattern. The observer class is the observer in this implementation (as the name suggests) and any QObject based class can be a subject. One way to think about an observer is to think of it as a context in your application to which certain subjects can be attached or detached. An example of such a context is the observer which manages plugins in the %Qtilities extension system. When plugins are loaded they are attached to this context and become visible in the list of loaded plugins. Another example would be different instances of a scripting engine. When new objects are created inside the scripting engine they exist in that context. It can then for example be possible to have multiple scripting engines within the same application, where different objects belongs to different script engines or are shared between the engines using Observers.

The %Qtilities implementation of this pattern is a very powerful addition to any Qt programmer's toolbox and this article will explain the many different features of the implementation. 

Table of contents:
- \ref observers_introduction
	- \ref creating_contexts
	- \ref sharing_objects
	- \ref observer_subject_IDs
	- \ref object_categories
	- \ref object_lifetimes
        .
- \ref qtilities_properties
	- \ref different_properties
	- \ref important_properties
	- \ref monitoring_property_changes
	.
- \ref subject_filters
	- \ref subject_filter_attachment_involvement
	- \ref context_activity
	- \ref managing_names
	- \ref managing_object_types
	- \ref custom_filters
	.
- \ref observer_advanced_topics
	- \ref context_dependency
	- \ref observer_hints
	- \ref batch_processing
	- \ref modification_state
	- \ref exporting_importing
	- \ref building_trees
	- \ref access_modes
	.
</td>

<td style="width:20%; vertical-align: top; margin:0px 0px 0px 0px;">
<table style="table-layout:auto;
	margin:0px 0px 0px 0px; 
  width: 100%;
	border-width:0px 0px 0px 0px; 
	border-color:#7F7F7F;
  background-color: #d1d3d4;">
<tr>
<td style="background-color: #5a5c5e; text-align: center">
<h2 style ="color:#FFFFFF">First Steps</h2>
</td>
</tr>
<tr>
<td>
- <a href="page_getting_started.html">Getting Started</a><br>
- <a href="page_the_basics.html">The Basics</a><br>
- <a href="page_examples_and_plugins.html">Examples and Plugins</a><br>
</td>
</tr>
<tr>
<td style="background-color: #5a5c5e; text-align: center">
<h2 style ="color:#FFFFFF">Overviews</h2>
</td>
</tr>
<tr>
<td>
- <a href="page_action_management.html">Action Management</a><br>
- <a href="page_tree_structures.html">Building Trees</a><br>
- <a href="page_debugging.html">Debugging Applications</a><br>
- <a href="page_extension_system.html">Extension System</a><br>
- <a href="page_factories.html">Factories</a><br>
- <a href="page_logging.html">Logging</a><br>
- <a href="page_modules_overview.html">Modules</a><br>
- <a href="page_object_management.html">Object Management</a><br>
- <a href="page_observers.html">Observers</a><br>
- <a href="page_observer_widgets.html">Observer Widgets</a><br>
- <a href="page_project_management.html">Project Management</a><br>
- <a href="page_tasking.html">Tasking</a><br>
- <a href="page_widget_set.html">Widget Set</a><br>
</td>
</tr>
</table>
</td>

</tr>
</table>

\section observers_introduction Introduction through simple examples

This section will introduce basic observer operations through blocks of example code. It is important to understand these example blocks of code before moving on to the sections that follows.

\subsection creating_contexts First steps: Creating an observer contexts and attaching objects to it

This example shows how to create your first observer class and attach objects to it.

\code
#include <QtilitiesCore>
using namespace QtilitiesCore;

// Create the observer
Observer* observerA = new Observer;

// Create the objects
QPointer<QObject> object1 = new QObject;
QPointer<QObject> object2 = new QObject;

// Attach objects to observers
observerA->attachSubject(object1);
observerA << object2;
\endcode

\subsection sharing_objects Object sharing: Attaching an object to multiple contexts

A very powerful feature of the way observers handle attached subjects is that they can be attached to multiple observers. We can append the following to the above example:

\code
// Create another observer
Observer* observerB = new Observer;

// Attach objects to observers
observerB->attachSubject(object1);
observerB->attachSubject(object2);

// Get the references to all children attached to an observer
QList<QObject*> children_B = observerB->subjectReferences();

// Get the number of children
int number_children_B = observerB->subjectCount();

// Get the number of parents
int parent_count_1 = Observer::parentCount(object1);

// Get the references of any objects' parents
QList<Observer*> parents_object1 = Observer::parentReferences(object1);
\endcode

The above code example also shows how to get the references to an object's parents, and how to get the number of subjects inside an observer context along with and their references.

\subsection observer_subject_IDs Observer & Subject IDs: Accessing objects using unique IDs

Every observer created in your application will have an unique integer ID associated with it. This value is assigned to the observer by the object manager in its constructor. The ID of an observer can be accessed using the Qtilities::Core::Observer::observerID() function. It is also possible to access any observer instance through the Qtilities::Core::ObjectManager::observerReference() function. 

When an object is attached to one or more observers it is assigned an unique ID within each context. The ID is stored on the object using the Qtilities::Core::Properties::qti_prop_OBSERVER_MAP dynamic property. The \ref qtilities_properties section explores dynamic properties in detail.

\subsection object_categories Object categories: Organizing objects into categories inside a context

When objects should be managed into categories inside an observer it can be done by setting the Qtilities::Core::Properties::qti_prop_CATEGORY_MAP property on an object before attaching it to an observer which has its Qtilities::Core::Observer::HierarchicalDisplay hint set to categorized hierarchy. When viewing such an observer using the Qtilities::CoreGui::ObserverWidget class it will show the objects under such observers using the categories specified on the objects.

For examples of how observer widgets visualize categories, see the \ref hierarchical_display section of the \ref page_observer_widgets article.

\subsection object_lifetimes Object lifetimes: Managing object lifetimes using observers

When attaching objects to observers, it is possible to specify the way the object should be managed by the observer context. The possible management options are defined in the Qtilities::Core::Observer::ObjectOwnership enumeration. The ownership of any object observed by one or more observers is stored using the Qtilities::Core::Properties::qti_prop_OWNERSHIP property.

\section qtilities_properties Dynamic properties used and managed by Observers

%Observer classes use the dynamic property features of QObject classes extensively to manage objects in contexts. This section will explain how to use these properties, which properties exists and how property changes can be monitored. The sections to follow will explain the different properties which is used in %Qtilities, however new custom properties can easily be created and added to objects since the observer property classes are basically wrappers around QVariant. 

The object manager provides the Qtilities::Core::ObjectManager::propertyExists() function which can be used to check if a property exists on an object.

\subsection different_properties Different property types

At present, two types of properties are used:
- Qtilities::Core::MultiContextProperty : Used to store properties which are different between different contexts.
- Qtilities::Core::SharedProperty : Used to store properties which remain the same between different contexts.

Getting and setting of properties are done by the Qtilities::Core::Observer class which provides easy to use functions to set and get properties and their values. For shared properties it is easy to get and set the value of the property because we do not need to know the context since the value is the same for all contexts. For normal observer properties we need to know the context since the value is different for different contexts. See the respective property class documentation for more information about setting and getting different properties.

\subsection important_properties Important properties and how they are interpreted

As mentioned earlier in this section, %Qtilities uses a number of properties internally to manage objects in different contexts. All these properties are defined and documented in the Qtilities::Core::Properties namespace.

Some of these properties are reserved and cannot be changed (see the Permission section of each property's description) by the developer. These properties should not be modified, and if an attempt is made to 
modify them the property change event will be filtered by the observer and the property will stay unchanged. A list of reserved properties can be obtained through the Qtilities::Core::Observer::reservedProperties() method and the Qtilities::Core::Observer::propertyChangeFiltered() signal will be emitted when a property change was filtered.

Other properties can be set by the developer before attachment to observers to provide information to the observer about how the object must be treated. The documentation of the different properties provides more details.

\subsection monitoring_property_changes Monitoring property changes and changing properties

A powerful feature of the observer and observer property combination is that changes to properties are detected by observers and handled accordingly. A list of the monitored properties for a specific context can be obtained using the Qtilities::Core::Observer::monitoredProperties() function. This function also takes into account the monitored properties of all subject filters installed in the context.

To change a property is easy, but care should be taken when changing properties which are different between contexts:
\code
// First check if the property exists. If it does we need to change only the context we
// are interested in. If we replace the complete property we will lose the information
// for all other contexts.
if (ObjectManager::propertyExists(obj,qti_prop_CATEGORY_MAP)) {
    MultiContextProperty category_property = ObjectManager::getMultiContextProperty(obj,qti_prop_CATEGORY_MAP);
    category_property.setValue(qVariantFromValue(NEW_CATEGORY),OBSERVER_ID);
    ObjectManager::setMultiContextProperty(obj,category_property);
} else {
    MultiContextProperty category_property(qti_prop_CATEGORY_MAP);
    category_property.setValue(qVariantFromValue(NEW_CATEGORY),OBSERVER_ID);
    ObjectManager::setMultiContextProperty(obj,category_property);
}
\endcode

If an observer has an activity policy filter installed and the Qtilities::Core::Properties::qti_prop_ACTIVITY_MAP property on an object within the context is changed, the change will be detected by the observer and passed to the activity policy filter. The filter will then validate the activity state of all objects in the context. The way the validation is performed depends on the setup of the activity policy filter. The property change is thus validated by all the attached subject filters and by the observer itself. 

For properties which has the "Change Notifications" parameter as Yes in their documentation, notifications are available when property changes were valid in the following ways (always both):
- The Qtilities::Core::Observer::monitoredPropertyChanged() signal is emitted with information about the change.
- When Qtilities::Core::Observer::toggleQtilitiesPropertyChangeEvents() is enabled a Qtilities::Core::QtilitiesPropertyChangeEvent event is delivered to the object on which the change took place. It is important to note that events can only be delivered to objects which are in the same thread as the observer. This is a Qt limitation and if this is a problem in your implementation you should rather use the first notification method. If an object is attached to two observers, the notifications will not happen more than once if necessary.

It is easy to catch property change events on an object to which it is delivered. For example:
\code
bool MyObject::eventFilter(QObject *object, QEvent *event) {
    if (object == this && event->type() == QEvent::User) {
        QtilitiesPropertyChangeEvent* qtilities_event = static_cast<QtilitiesPropertyChangeEvent *> (event);
        if (qtilities_event) {
            // Lets check for example if the qti_prop_NAME property changed:
            if (!qstrcmp(qtilities_event->propertyName().data(),qti_prop_NAME)) {
                // Remembering that qti_prop_NAME is managed by a name manager and that 
                // it is sync'ed with objectName(), we can now get the new name of the object.
                QString new_name = objectName();
            }
        }
    }
    return false;
}
\endcode

\section subject_filters Subject filters

Subject filters are a feature of the observer architecture which allows control over object attachment and detachment, as well as monitoring of properties introduced by the subject filter. 

All subject filters must inherit Qtilities::Core::AbstractSubjectFilter. You can install subject filters using the Qtilities::Core::Observer::installSubjectFilter() function and uninstall subject filters using the Qtilities::Core::Observer::uninstallSubjectFilter() function. A subject filter can only be used in one observer at any time.

\subsection subject_filter_attachment_involvement Attaching an object to an observer context with subject filters

When attaching an object to an observer context which has subject filters installed, these filters are called during the attachment process to validate the attachment and to make sure all other objects in the context are in the correct state as well after the object was attached. Subject filters normally also add properties to the attached object. The diagram below shows when the Qtilities::Core::AbstractSubjectFilter::initializeAttachment() and Qtilities::Core::AbstractSubjectFilter::finalizeAttachment() functions are called during attachment of an object.

\image html subject_filters_attachment.jpg "Subject Filter Attachment Sequence"

Detachment of an object can happen in two ways:
- By calling the Qtilities::Core::Observer::detachSubject() function
- By deleting an object observed by an observer. 

The detachment process is slightly different for the two cases. The first diagram below shows the case where the detach function is called directly.

\image html subject_filters_detachment.jpg "Subject Filter Detachment Sequence"

The diagram below shows the case where the object is deleted while attached to the observer. In this case the private slot \p handle_deletedSubject() on the observer instance is called.

\image html subject_filters_object_deletion.jpg "Subject Filter Detachment Sequence (Object Deletion)"

Another important feature of the observer implementation is that subject filters can indicate to the observer in which they are installed which properties must be monitored. This allows subject filters to validate property changes to the properties added to subjects by the filter.

\subsection context_activity Managing context activity

A common requirement in a context is to manage the activity of objects within the context. The Qtilities::Core::ActivityPolicyFilter class was designed for this purpose and has many different options allowing precise control over object activity within a context. See the class documentation for more information about this filter.

\subsection managing_names Managing names within a context

Another common requirement in a context is to manage the names of objects within the context. The Qtilities::CoreGui::NamingPolicyFilter class was designed for this purpose and has many different options allowing precise control over object names within a context. See the class documentation for more information about this filter.

\subsection managing_object_types Managing object types within a context

From a developers perspective it might be useful to control the type of objects which can be attached to a context. The Qtilities::Core::SubjectTypeFilter class was designed for this purpose and has different filtering options allowing precise control over what types of objects can be attached to a context. See the class documentation for more information about this filter.

\subsection custom_filters Creating custom subject filters

Creating custom subject filters is an easy task if you understand how the initialization and finalization diagrams shown above work. The Qtilities::Core::SubjectFilterTemplate class is included in the Core module and should be used as a starting point when creating new subject filters. The new filter class needs to inherit from Qtilities::Core::AbstractSubjectFilter and re-implement the virtual abstract functions in order to work. The source code of the subject filters which comes as part of %Qtilities is a good place to start when looking for examples of filter implementations.

\section observer_advanced_topics Advanced topics

\subsection context_dependency Context dependency: Creating context aware classes

In some cases it is desirable to have a class which depends on an observer context. For such cases the Qtilities::Core::ObserverAwareBase class was created.
Classes can inherit from this class which will add two functions to your class:
- \p setObserverContext() : A function to set the observer context for the class.
- \p observerContext() : A function to get the observer context for the class.

It is then possible to access the observer context using the protected variable \p d_observer. This reference is a QPointer, thus it will detect when the observer context is deleted and will be set to 0.

\subsection observer_hints Observer hints: Define the way your context must be displayed

The observer class provides a concept called observer hints. These hints are called display hints since they guide widgets displaying the context of the observer. The available hints are defined in the Qtilities::Core::ObserverHints class and can be used on any observer by calling the Qtilities::Core::Observer::useDisplayHints() function after the observer was constructed. The \ref page_observer_widgets article explores these different hints and shows what their effects are on the visualized observer context.

\subsection batch_processing Batch processing: Optimization using processing cycles

When doing intensive processing on an observer, for example attaching 1000 objects to it, things can get pretty slow since each attachment will emit signals which will cause views connected to the observer to be updated. For this reason the observer class provides the concept of processing cycles.

It is possible to start a processing cycle using the Qtilities::Core::Observer::startProcessingCycle() function. After this function call you can do intensive processing on the observer and when you are done the processing cycle can be finished using the Qtilities::Core::Observer::endProcessingCycle(). After the processing cycle was ended the necessary updates can be done manually. For example if you changed the layout of the observer, you can call the Qtilities::Core::Observer::refreshViewsLayout() function. If you only changed data in the context, you can call the Qtilities::Core::Observer::refreshViewsData() function.

\subsection modification_state Modification state: Check if an observer changed

The observer class implements the Qtilities::Core::Interfaces::IModificationNotifier interface. Thus it is possible to monitor the notification state of an observer and its subjects. When attaching an object to an observer the attachment function will check if the object implements this interface as well, and if it does the observer will take the object's state into account when reporting on its own modification state. Observers also take any changes to themselves into account, this includes hierarchical structure changes, hints etc. 

Observers also provide a number of signals which can be monitored if you are interested in specific changes in an observer context. See the Qtilities::Core::Observer class documentation for more information.

\subsection exporting_importing Exporting and importing observers

The observer class implements the Qtilities::Core::Interfaces::IExportable interface making it exportable. When a tree is exported, a recursive search for any objects in the tree implementing this interface occurs and the objects found is part of the exported object.

For more information on this topic, see \ref tree_xml for examples of XML exports on observer structures.

\subsection building_trees Using observers to build hierarchical trees

Observers has the only requirement that objects attached to them must be QObjects, therefore it is also possible to attach observers to other observers because an observer is a QObject. This makes construction of tree structures using observer very easy. For more information, see the \ref page_tree_structures article.

\subsection access_modes Access modes: Define user access on a per context basis

Observers provide access control functionality through the Qtilities::Core::Observer::setAccessMode() and Qtilities::Core::Observer::setAccessModeScope() functions. The possible access modes are provided through the Qtilities::Core::Observer::AccessMode enumeration. Item views and observer functions take the access mode into account when displaying observer contexts or when attempting to modify observers. A convenient function that can be used to check if the access mode of an observer allows the observer to be changed is Qtilities::Core::Observer::isConst(). Access modes can also be set on a category level, for more information see Qtilities::Core::Observer::accessModeScope().

The \ref access_mode section of the \ref page_observer_widgets article shows how the observer widget class customizes its display of observer contexts for different access modes.

*/
